package com.liuyucheng.generic.basic;

import org.apache.shiro.crypto.hash.Hash;

import java.util.*;

/**
 * 抽奖器
 * @param <T>
 */
public class ProductGetter<T> {

    private T product;

    Random random = new Random();

    //奖品池
    ArrayList<T> list = new ArrayList<>();

    public void addProduct(T t){
        list.add(t);
    }

    public T getProduct() {
        product = list.get(random.nextInt(list.size()));
        return product;
    }

    /**
     * 定义泛型方法
     * @param list 参数
     * @return 结果
     * @param <E> 泛型标识，具体类型由调用方法的时候来指定，
     *           这里的E和类上面定义的T没有关系，相互独立的
     *           就算改成T，也还是跟上面的T没有关系
     */
    public <E> E getProduct(ArrayList<E> list){
        return list.get(0);
    }

    /**
     * 泛型方法可以定义为静态，而且是多个类型的
     * @param a 对象a
     * @param b 对象b
     * @param c 对象c
     * @param <A> A类型
     * @param <B> B类型
     * @param <C> C类型
     */
    public static <A,B,C> void printType(A a,B b,C c){
        System.out.println("a.getClass().getName() = " + a.getClass().getName());
        System.out.println("b.getClass().getName() = " + b.getClass().getName());
        System.out.println("c.getClass().getName() = " + c.getClass().getName());
    }

    /**
     * 泛型方法声明可变数量的参数
     * @param e 接收到的参数集合
     * @param <E> 参数类型
     */
    public static <E> void print(E... e){
        for(E item : e){
            System.out.println(item);
        }
    }

    //堆污染问题
    public static void heapPollution(Set<Integer> set){
        set.add(100);
    }
    public static void main(String[] args) {
        //Set未指定具体类型，可以作为参数传进heapPollution方法
        Set set = new TreeSet();
        heapPollution(set);
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            System.out.println("next = " + next);
        }
    }
}
